package com.mallcai.bigdata.ladon.service.report.impl.handler;

import com.cake.bigdata.starter.exception.category.BusinessException;
import com.mallcai.bigdata.ladon.client.vo.ReportDataVO;
import com.mallcai.bigdata.ladon.datasource.AbstractJdbcHandler;
import com.mallcai.bigdata.ladon.datasource.HandlerFactory;
import com.mallcai.bigdata.ladon.datasource.RunInfoResult;
import com.mallcai.bigdata.ladon.dpl.entity.common.Datasource;
import com.mallcai.bigdata.ladon.dpl.entity.report.ReportSql;
import com.mallcai.bigdata.ladon.service.report.impl.ReportDataVoExtractor;
import com.mallcai.bigdata.ladon.service.report.impl.ReportQueryContext;
import com.mallcai.bigdata.ladon.service.report.impl.handler.support.MapParamPreparedStatementSetter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;

/**
 * described :
 *
 * @author CaKeDou
 * @date 2019-09-11 20:08
 * Modify:
 */
@Slf4j
@Component
@Order(7000)
public class ReportQueryPagingHandler extends AbstractReportQueryBothHandler {

    private static final RunInfoResult<ReportDataVO> EMPTY_RESULT = RunInfoResult.createEmptyResult(ReportDataVO.EMPTY);

    @Override
    public void preInternal(ReportQueryContext context) {
        ReportSql reportSql = context.getReportSql();

        if (isPaging(reportSql.getPaging(), context.getReportQueryParam().isExportReport())) {
            Map<String, Object> originalParams = context.getOriginalParams();
            Integer pageSize = (Integer) originalParams.get("page_size");
            Integer pageNum = (Integer) originalParams.get("page_num");
            //1.检查分页参数
            if (pageSize == null) {
                throw new BusinessException("分页查询时,缺少page_size参数");
            }
            if (pageNum == null) {
                throw new BusinessException("分页查询时,缺少page_num参数");
            }
            //2.先查询一下总条数
            String sql = context.getSql();
            String totalSql = "select count(1) as total_count from(" + sql + ") ladon_count_wrap";
            log.info(totalSql);
            Datasource datasource = context.getDatasource();
            AbstractJdbcHandler handler = HandlerFactory.getHandler(context.getDatasource());
            RunInfoResult<ReportDataVO> runInfoResult = handler.queryDataWithRunInfo(datasource, totalSql,
                    new MapParamPreparedStatementSetter(context.getSqlParams(), reportSql.getTimeout()),
                    new ReportDataVoExtractor());

            if (!runInfoResult.isSuccess()) {
                context.setResult(runInfoResult);
                return;
            }
            List<Map<String, Object>> rows = runInfoResult.getData().getRows();
            Long totalCount = 0L;
            if (rows != null) {
                totalCount = (Long) rows.get(0).get("total_count");
            }
            if (totalCount == 0L) {
                context.setResult(EMPTY_RESULT);
                return;
            }
            context.setTotalCount(totalCount);
            //3.根据分页参数更改sql
            context.setSql(sql + " limit " + ((pageNum - 1) * pageSize) + "," + pageSize);
        }


    }

    @Override
    protected void postInternal(ReportQueryContext context) {
        //将总条数放进去
        ReportSql reportSql = context.getReportSql();
        if (isPaging(reportSql.getPaging(), context.getReportQueryParam().isExportReport())) {
            ReportDataVO data = context.getResult().getData();
            if(data != null){
                data.setTotalCount(context.getTotalCount());
            }

        }
    }

    private boolean isPaging(Integer paging, boolean exportReport) {
        return paging != null && paging > 0 && !exportReport;
    }
}
